function Compile(vm, el) {
  this.vm = vm
  this.el = document.querySelector(el)
  this.fragment = null
  this.init()
}

Compile.prototype = {
  init: function() {
    if (this.el) {
      this.fragment = this.nodeToFragment(this.el)
      this.compileElement(this.fragment)
      this.el.appendChild(this.fragment)
    } else {
      console.log('未找到dom节点');
    }
  },
  nodeToFragment: function(el) {
    var fragment = document.createDocumentFragment();
    var firstChild = el.firstChild
    while (firstChild) {
      fragment.appendChild(firstChild); //fragment.appendChild原dom中的元素会被移除
      firstChild = el.firstChild
    }
    return fragment
  },
  compileElement: function(el) {
    var childNodes = el.childNodes;
    var reg = /\{\{(.*)\}\}/;
    [].slice.call(childNodes).forEach(node => {
      var text = node.textContent;
      if (this.isTextNode(node) && reg.test(text)) {
        this.compileText(node, reg.exec(text)[1])
      }
      var nodeList = node.childNodes
      if (nodeList != null && nodeList.length > 0) {
        this.compileElement(node)
      }
    })

  },
  compileText: function(node, exp) {
    var self = this
    var originText = this.vm[exp]
    this.updateText(node, originText)
    new Watcher(this.vm, exp, function(newVal) {
      self.updateText(node, newVal)
    })
  },
  updateText: function(node, exp) {
    node.textContent = typeof exp === 'undefined' ? '' : exp
  },
  isTextNode: function(node) {
    return node.nodeType === 3
  }
}